crack my points (DLL + Loader)
Change value points from 100 to more than 100
Original crackme output:

The goal is to change it from displaying 100 to any value greater than 100.
So... this is not what I am typically used to in terms of comparing passwords and keygens.
The crackme contains two files: a .dll and a .exe. The DLL uses the EXE purely as its host loader. We cannot run the DLL solo directly, but the EXE loads the DLL into memory, specifically triggering the code inside the DllMain function.
Looking at main for Loader.exe, we can see Crackme.dll being loaded via LoadLibraryA. As soon as that happens, Windows automatically invokes DllMain with DLL_PROCESS_ATTACH, which runs the crackme payload and gives the output you have 100. Once LoadLibraryA succeeds, the loader just frees the library, sleeps for 3 seconds, and exits cleanly. Otherwise it takes the other branch and displays a console output saying DLL not loaded.

So our entire focus is reversing the DLL. What to look out for:
- Console output: The text is printed to the console, so since this is a C++ binary, I'll be on the lookout for
std::cout(basic_ostream) - the stream object responsible for outputting data to the console. - The score loop: The value 100 looks like the result of a counter/accumulator loop somewhere, so I'll also hunt for loop structures.
- Hardcoded string anchors: Look for where the string
you haveis being assembled or referenced in memory.
For this, I used x64dbg as my primary dynamic debugger, and used IDA Pro to get a bird's-eye view of the overall control flow graph. I'm tryna get intune with x64dbg and this is where it begins.
DllMain Function
Reversing DllMain, I noticed the strings are scattered across different addresses rather than stored as one contiguous string. There is byte movement happening through the standard memmove function memmove(dest, src, count):


The full string gets put together at the destination address ending in EF49:

Then we hit the core loop that directly influences the value printed to the console:

In this loop, 3 key values change:
r8dstarts at89hedxstarts at1eaxstarts at0(the loop counter)
The blocking check is:
cmp eax, 64h ; 64h = 100 in decimal
jl crackme.1470 ; Jump if Less (Signed comparison)
The loop runs 100 times. With each iteration, inc edx increments edx, so by the end of the loop, edx reaches 65h (101).
Right after exiting the loop, it hits:
dec edx ; 65h - 1 = 64h (100 in decimal)
This 64h is moved into memory and passed into the formatting function, which converts the hex argument into the decimal string "100". That is where our "100" comes from!
The Patch
To solve the challenge, I needed to influence the value edx holds after the decrement so that it exceeds 100.
The cleanest way to do this is to patch the loop exit condition. In x64dbg, I patched the cmp eax, 64h instruction so the loop runs more iterations:
; Original:
cmp eax, 64h ; runs 100 times -> dec edx gives 100
; Patched:
cmp eax, 65h ; runs 101 times -> dec edx gives 101
With cmp eax, 65h, the loop runs 101 times. edx reaches 66h, and after dec edx, it becomes 65h (101 decimal). This gives us the target output: you have 101!

Beyond 127 (0x7F) "Why Larger Values Break
While experimenting with the patch, I noticed an interesting edge case: if you try setting the loop to run more than 127 times (e.g. cmp eax, 80h), the whole logic breaks, edx ends up at 2, r8 resets to its default, and the loop refuses to count up.
83 F8 64 -> cmp eax, 64h
Notice that EAX is 4 bytes wide, but the instruction only reserves 1 single byte for our number (64).
To compare them, the CPU has to stretch that 1-byte number into 4 bytes so they are the same size (this is called sign-extending - growing the number by copying its plus or minus sign):
- Numbers 0 to 127 (
0x00to0x7F): Are positive, so the CPU pads the empty space with zeros (stays positive +100). - 128 (
0x80): Has its minus sign flipped on! When the CPU stretches it, it pads it with minus signs, turning it into-128(0xFFFFFF80).
Because our loop uses jl (Jump if Less), it starts at 0 and checks if our counter is less than the target. But since 0 is already bigger than -128, the computer thinks it's already finished and bails out immediately without running the loop even once!
Result

